<?php

class Page_Block_Exception extends Page_Exception {}
class Page_Block_Invalid_Exception extends Page_Block_Exception {}

class Page_Block_Data {

	public function __construct($data){
		$this->data = explode('/', $data);
	}

	public function data_set($data){
		$this->data = $data;
	}

	public function data_all(){
		return $this->data;
	}

	public function data_top(){
		return isset($this->data[0]) ? $this->data[0] : null;
	}

	public function data_shift(){
		array_shift($this->data);
	}

}

abstract class Page_Block {

	// Core Methods

	abstract public static function Load($args);

	public function run(){

	}

	// Block Handler Methods

	public function output($child = null){
		$template = Output::getInstance()->Template(array('page','block'));
		if(isset($child)){
		        $template->module = $child;
		}
		return $template;
	}

	public static function Get($rids, $args){
		$rids = array_reverse($rids);
		$sources = array('');
		$block_data = false;
		$blocks = array();

		foreach($rids as $rid){
			$base = '';
			foreach($rid as $component){
				$sources[] = $base . $component;
				$base .= $component . '/';
			}
		}

		$sources = array_reverse($sources);

		if($args['parent']->data_top() == 'block'){
			$block_data = true;
			$args['parent']->data_shift();
		}

		foreach($sources as $source){
			$result = Database::getInstance()->query("SELECT * from page_blocks WHERE page = %s AND site = %u", $source, Site::getInstance()->getID());
			while($block = $result->fetch_assoc()){
				try {
					if($block_data && ( (int) $args['parent']->data_top() == ((int) $block['id']))){
						$args['parent']->data_shift();
						$args['data'] = $args['parent'];
					} else {
						$args['data'] = new Page_Block_Data($block['block']);
					}
			
					$module = Module::Get($args['data']->data_top());
					$args['data']->data_shift();
					$class = $module->Load_Section('Page_Block');
					$logic = call_user_func(array($class, 'Load'), $args);
					if($logic instanceof Page_Block){
						$blocks[] = $logic;
					} else {
						throw new Page_Block_Invalid_Exception($logic);
					}
				} catch (Exception $e){
					// Ignore Block
				}
			}
		}

		return $blocks;
	}

}
